13 Pandas groupby用法
13.1 引言分组聚合的分析价值
Split-Apply-Combine(分组-应用-合并)是数据分析的核心范式: 1. Split: 将数据分为多个组 2. Apply: 对每组应用函数 3. Combine: 合并结果
金融应用场景: - 按行业统计股票表现 - 按时间段计算收益率 - 按市场分组分析风险
13.2 groupby基础
# ⚠️ 平台原始代码 - 请原样输入至教学平台(注释除外),平台才会判定答案正确
import pandas as pd # 导入Pandas数据分析库
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', # 创建数据框df
'foo', 'bar'], # A列分组标签的续行数据
'B' : ['one', 'one', 'two', 'three', # "B"的数据序列
'two', 'two'], # B列分组标签的续行数据
'C' : [1, 5, 5, 2, 5, 5], # "C"的数据序列
'D' : [2.0, 5., 8., 1., 2., 9.]}) # "D"的数据序列
grouped = df.groupby('A')[['C', 'D']] # 按指定列分组聚合
result=grouped.transform(lambda x: (x - x.mean()) / x.std()) # 定义匿名函数result
print(result) # 输出分析结果数据13.3 聚合函数(Aggregation)
# =============================================================================
# 题目:分组聚合统计
# =============================================================================
# 本示例演示对分组数据应用常用聚合函数
# 金融应用:计算每只股票的平均收益率、每行业的总市值等
# ==================== 选择特定列分组 ====================
# 只对C、D两列进行分组聚合(排除不需要的列)
grouped = df.groupby('A')[['C', 'D']] # 双重索引选择特定列
# ==================== 应用聚合函数 ====================
# 计算每组的均值
print("均值:")
print(grouped.mean()) # mean()返回每组的平均值,NaN会被自动忽略
# 计算每组的总和
print(f"\n求和:")
print(grouped.sum()) # sum()返回每组的总和
# 计算每组的非缺失值计数
print(f"\n计数:")
print(grouped.count()) # count()统计每组的非空值数量
# 计算每组的标准差
print(f"\n标准差:")
print(grouped.std()) # std()计算标准差,衡量数据波动性
# ==================== 同时应用多个聚合函数 ====================
# 对每列应用多个统计函数
print(f"\n自定义统计:")
print(grouped.agg(['mean', 'std', 'min', 'max']))
# agg()可接收函数列表,同时计算均值、标准差、最小值、最大值13.4 transform转换操作
transform返回与原数据相同形状的结果。
# =============================================================================
# 题目:分组标准化转换
# =============================================================================
# 本示例演示使用transform进行组内标准化
# 金融应用:消除不同股票的价格量纲差异,便于比较
# ==================== 标准化转换 ====================
# 标准化公式: (x - mean) / std
# 将每组数据转换为均值为0、标准差为1的分布
result = grouped.transform(lambda x: (x - x.mean()) / x.std())
# transform()对每组应用函数,返回与原数据形状相同的DataFrame
# lambda x是匿名函数,x代表每组的数据
print("标准化结果:")
print(result) # 输出:原数据被标准化,但形状保持不变
# ==================== 验证标准化结果 ====================
# 验证:每组的均值应约等于0,标准差应约等于1
print(f"\n验证-每组均值:")
print(result.groupby(df['A']).mean())
# 对标准化后的数据再分组计算均值,应接近0
print(f"\n验证-每组标准差:")
print(result.groupby(df['A']).std())
# 对标准化后的数据再分组计算标准差,应接近1金融应用: 组内标准化,消除组间差异
13.5 filter过滤分组
# =============================================================================
# 题目:按条件过滤分组
# =============================================================================
# 本示例演示如何基于组的统计特征过滤整个组
# 金融应用:筛选出交易量活跃的股票、过滤掉小客户群体
# ==================== 过滤分组 ====================
# 保留C列均值>3的整个组(不是过滤行,是过滤组)
filtered = df.groupby('A').filter(lambda x: x['C'].mean() > 3)
# filter()对每组应用条件函数,返回满足条件的组的所有行
# 逻辑:如果某组的C列平均值>3,则保留该组的所有数据
print("过滤后的数据:")
print(filtered) # 输出:只包含C列均值>3的组的数据13.6 apply灵活应用
# =============================================================================
# 题目:对每组应用复杂自定义函数
# =============================================================================
# 本示例演示使用apply实现灵活的分组操作
# 金融应用:找出每只股票价格最高的交易日、计算每组的复合增长率等
# ==================== 定义自定义函数 ====================
# 自定义函数:找出每组D列最大的行
def get_max_row(group):
"""找出分组中D列最大的行"""
return group.loc[group['D'].idxmax()]
# group是每组的完整DataFrame
# idxmax()返回D列最大值的索引(行号)
# loc[]根据索引定位整行数据
# ==================== 对每组应用自定义函数 ====================
result = df.groupby('A').apply(get_max_row)
# apply()对每组应用自定义函数,可返回任意结构的DataFrame
print("每组D列最大的行:")
print(result) # 输出:每个组中D列最大的那一行数据